package br.com.fatecjp.pooai.gerenciador.taxi.behaviour;

import jade.core.behaviours.Behaviour;
import jade.domain.DFService;
import jade.domain.FIPAException;
import jade.domain.FIPAAgentManagement.DFAgentDescription;
import jade.domain.FIPAAgentManagement.ServiceDescription;
import jade.lang.acl.ACLMessage;
import br.com.fatecjp.pooai.gerenciador.taxi.agent.AgenteTaxi;
import br.com.fatecjp.pooai.gerenciador.taxi.ambiente.Posicao;
import br.com.fatecjp.pooai.gerenciador.taxi.message.ConteudoMensagemAgente;
import br.com.fatecjp.pooai.gerenciador.taxi.message.TipoMensagemAgente;
import br.com.fatecjp.pooai.gerenciador.taxi.message.parser.ConteudoMensagemAgenteParser;
import br.com.fatecjp.pooai.gerenciador.taxi.message.parser.RespostaRegistroTaxiParser;
import br.com.fatecjp.pooai.gerenciador.taxi.service.NomeServico;

public class RegistrarTaxiBehaviour extends Behaviour {

	private static final long serialVersionUID = 14714471290655584L;

	private boolean taxiRegistrado;

	private ConteudoMensagemAgenteParser conteudoMsgAgenteParser;
	private RespostaRegistroTaxiParser respostaRegTaxiParser;

	public RegistrarTaxiBehaviour(AgenteTaxi agent) {
		super(agent);
		this.taxiRegistrado = false;
		this.conteudoMsgAgenteParser = new ConteudoMensagemAgenteParser();
		this.respostaRegTaxiParser = new RespostaRegistroTaxiParser();
	}

	public void action() {

		ServiceDescription descricaoServico = new ServiceDescription();
		descricaoServico.setName(NomeServico.REGISTRO_TAXI.toString());

		DFAgentDescription descricaoAgente = new DFAgentDescription();
		descricaoAgente.addServices(descricaoServico);

		DFAgentDescription[] agentesEncontrados = null;
		try {
			agentesEncontrados = DFService.search(myAgent, descricaoAgente);
		} catch (FIPAException e) {
			throw new RuntimeException(e);
		}

		if (agentesEncontrados != null && agentesEncontrados.length > 0) {

			descricaoAgente = agentesEncontrados[0];

			ACLMessage requisicaoRegistro = new ACLMessage(ACLMessage.REQUEST);
			requisicaoRegistro.setSender(myAgent.getAID());
			requisicaoRegistro.addReceiver(descricaoAgente.getName());

			ConteudoMensagemAgente conteudoRequisicao = new ConteudoMensagemAgente(
					TipoMensagemAgente.REGISTRO_TAXI.getCode());
			requisicaoRegistro.setContent(this.conteudoMsgAgenteParser
					.toString(conteudoRequisicao));

			myAgent.send(requisicaoRegistro);

			boolean respostaRecebida = false;

			while (!respostaRecebida) {

				ACLMessage resposta = myAgent.receive();
				if (resposta == null) {
					this.block();
				} else if (resposta.getPerformative() == ACLMessage.CONFIRM) {

					ConteudoMensagemAgente conteudoResposta = this.respostaRegTaxiParser
							.parse(resposta.getContent());

					if (conteudoResposta != null) {

						respostaRecebida = true;
						AgenteTaxi agenteTaxi = (AgenteTaxi) myAgent;
						agenteTaxi.setPosicaoAtual((Posicao) conteudoResposta
								.getConteudo()[0]);

						this.taxiRegistrado = true;

						myAgent.addBehaviour(new MovimentarTaxiBehaviour(
								getAgent()));

					}

				}

			}

		}

	}

	public boolean done() {
		return this.taxiRegistrado;
	}

	public AgenteTaxi getAgent() {
		return (AgenteTaxi) this.myAgent;
	}

}
